package hu.szyrt.bug;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import hu.szyrt.bug.adapters.CommentAdapter;
import hu.szyrt.bug.connections.CommentLoadConnection;
import hu.szyrt.bug.connections.CommentSendConnection;
import hu.szyrt.bug.connections.DealConnection;
import hu.szyrt.bug.connections.FacebookConnection;
import hu.szyrt.bug.db.DBHandler;
import hu.szyrt.bug.db.DiscountHandler;
import hu.szyrt.bug.dialogs.BUGDialog;
import hu.szyrt.bug.login.LoginHandler;
import hu.szyrt.bug.models.Comment;
import hu.szyrt.bug.models.ContactMenu;
import hu.szyrt.bug.models.PlaceItem;
import hu.szyrt.bug.utils.Assets;
import hu.szyrt.bug.utils.Utils;
import hu.szyrt.bug.views.PlaceImageView2;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.Html;
import android.text.Spannable;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.TextView.BufferType;

public class PlaceActivity extends Activity {

	public final static String PLACE_ID 	 = "place_id",
							   HIGHLIGHTS_ID = "highlights_id";
	
	LoginHandler loginHandler;
	DBHandler dbHandler;
	PlaceItem placeItem;
	Assets assets;
	
	View headerView;
	ListView placeListView;
	
	Button backButton;
	PlaceImageView2 polaroid;
	TextView description;
	View dealBox;
	TextView dealCount,
			 dealDescription;
	Button useDealButton,
		   placeContactButton,
		   placeCheckInAndShareButton;
	TextView commentsAndTipsTextView;
	EditText newCommentEditText;
	Button newCommentSendButton;
	
	
	CommentAdapter commentAdapter;
	BUGDialog dialog;
	
	FacebookConnection facebookConnection = new FacebookConnection(this);
	
	LocationManager locationManager;
	Location latestKnowLocation;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.category_place);

		assets = new Assets(this);
		dbHandler = new DBHandler(this);
		loginHandler = new LoginHandler(this);
		
		boolean hasPlaceID = getIntent().getExtras() != null && getIntent().getExtras().containsKey(PLACE_ID);
		boolean hasHighlightsID = getIntent().getExtras() != null && getIntent().getExtras().containsKey(HIGHLIGHTS_ID);
		
		int placeID = hasPlaceID ? 
				getIntent().getExtras().getInt(PLACE_ID) : 
				(hasHighlightsID ? getIntent().getExtras().getInt(HIGHLIGHTS_ID) : -1);
		
		if(placeID <= 0){
			finish();
			return;
		}
				
		if(hasPlaceID){
			placeItem = dbHandler.loadPlace(placeID, false);
		}else if(hasHighlightsID){
			placeItem = dbHandler.loadPlace(placeID, true);
		}
		
		if(placeItem == null){
			finish();
			return;
		}
		
		headerView = View.inflate(this, R.layout.category_place_header, null);
		
		backButton = (Button)headerView.findViewById(R.id.backButton);
		backButton.setText(placeItem.getName());
		backButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				finish();
			}
		});
		
		description = (TextView)headerView.findViewById(R.id.description);
		description.setText(placeItem.getDescription());
		description.setLinkTextColor(Color.BLACK);
		description.postDelayed(new Runnable() {
			public void run() {
				if(description.getLineCount() > 12){ // 13 a maxLines, de nincs get MaxL ines csak API 16-tól :S
					int lastVisibleCharacterIndex = description.getLayout().getLineVisibleEnd(10);
					String cuttedText = description.getText().subSequence(0, lastVisibleCharacterIndex).toString();
					String newText = cuttedText + " <b>" + getString(R.string.next) + "</b>";
					description.setMaxLines(14);
					description.setText(Html.fromHtml(newText), BufferType.EDITABLE);
					Spannable spans = description.getEditableText();					
					spans.setSpan(new ClickableSpan() {
						public void onClick(View widget) {
							dialog.setMessage(placeItem.getDescription());
							dialog.setPositiveButton(R.string.ok, null);
							dialog.show();
						}
						
					}, lastVisibleCharacterIndex + 1, spans.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
					description.setText(spans);
					description.setMovementMethod(LinkMovementMethod.getInstance());					
				}
			}
		},10);
		
		polaroid = (PlaceImageView2)headerView.findViewById(R.id.polaroid);
		polaroid.setImageBitmap(assets.loadPolaroid(placeItem.getImagePolaroid(), 2));
		polaroid.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {				
				GalleryActivity.open(PlaceActivity.this, new String[]{
						placeItem.getImage1(),
						placeItem.getImage2()
				});
			}
		});
		
		if(placeItem.getHighlighstNumber() > 0 && placeItem.hasDiscount()){
			polaroid.setStampImage1(assets.loadCategoryIcon("highlights.png", 2));
			polaroid.setStampImage2(assets.loadCategoryIcon("deals.png", 2));
		} else if(placeItem.getHighlighstNumber() > 0){
			polaroid.setStampImage1(assets.loadCategoryIcon("highlights.png", 2));
		}else if(placeItem.hasDiscount()){
			polaroid.setStampImage1(assets.loadCategoryIcon("deals.png", 2));
		}
				
		dealBox = headerView.findViewById(R.id.deal_box);
		dealCount = (TextView)headerView.findViewById(R.id.deal_count);
		dealDescription = (TextView)headerView.findViewById(R.id.deal_description);
		useDealButton = (Button)headerView.findViewById(R.id.use_deal);				
		if(placeItem.getDiscountType() == 10){
			dealBox.setVisibility(View.GONE);			
		}else{			
			dealCount.setText(placeItem.getDiscountType() == 2 ? "COOL\nDEAL" : String.valueOf(placeItem.getDiscountValue() + "%"));
			dealCount.setTextSize(TypedValue.COMPLEX_UNIT_SP, placeItem.getDiscountType() == 2 ? 26 : 32);
			dealDescription.setText(placeItem.getDiscountDescription());
			dealBox.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					
					dialog = new BUGDialog(v.getContext());		
					dialog.setTitle(R.string.deals);
					dialog.setMessage(R.string.deal_confirm);			
					dialog.setPositiveButton(R.string.ok, new OnClickListener() {
						public void onClick(View v) {
							dialog.dismiss();
							useTheDeal();
						}
					});
					dialog.setNegativeButton(R.string.cancel, null);
					dialog.show();
					
				}
			});
		}
		
		placeContactButton = (Button)headerView.findViewById(R.id.place_contact);		
		placeContactButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				showContactsMapAndMore();
			}
		});
		
		placeCheckInAndShareButton = (Button)headerView.findViewById(R.id.place_check_and_share);		
		placeCheckInAndShareButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				shareOnFacebook();
			}
		});
		
		commentsAndTipsTextView = (TextView)headerView.findViewById(R.id.commentsAndTipsTextView);
		commentsAndTipsTextView.setTypeface(assets.getButtonTypeface());
		newCommentEditText = (EditText)headerView.findViewById(R.id.new_commen_text);		
		newCommentSendButton = (Button)headerView.findViewById(R.id.new_commen_send);
		newCommentSendButton.setTypeface(assets.getButtonTypeface());
		newCommentSendButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				sendComment();
			}
		});
		
		// Hozzáadás a listához
		placeListView = (ListView)findViewById(R.id.place);
		placeListView.addHeaderView(headerView);
		placeListView.setAdapter(null);
		
		this.dialog = new BUGDialog(this);		
		
		locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
	}
	
	@Override
	protected void onResume() {	
		super.onResume();		
		loadComments();
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5* 1000, 20, locListener);
		locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5 * 1000, 20, locListener);
	}
	
	@Override
	protected void onPause() {
		locationManager.removeUpdates(locListener);
		super.onPause();
	}
	
	private LocationListener locListener = new LocationListener() {
		public void onStatusChanged(String provider, int status, Bundle extras) {}
		public void onProviderEnabled(String provider) {}
		public void onProviderDisabled(String provider) {}
		public void onLocationChanged(Location location) {
			latestKnowLocation = location;
		}
	};
	
	// Facebook share -----------------------------------------
	private void shareOnFacebook(){
		final BUGDialog errDialog = new BUGDialog(this);
						errDialog.setTitle(R.string.errors);
						errDialog.setPositiveButton(R.string.ok, null);						
		
		if(Utils.isInternetAvailable(this)){
			facebookConnection.setNotify(new FacebookConnection.Notify() {
				public void onSuccess() {
					// Kikommentezve Facebook Android SDK miatt, ugyanúgy Complete ha Cancel-re klikkel a user
					// https://developers.facebook.com/bugs/154696481331669
					// https://developers.facebook.com/bugs/413571942015440
					//Toast.makeText(PlaceActivity.this, R.string.place_check_and_share_success, Toast.LENGTH_LONG).show();
				}			
				public void onError() {
					errDialog.setMessage(facebookConnection.getErrorText());
					errDialog.show();
				}
			});
			facebookConnection.shareAndPostOnWall(
					"",
					getString(R.string.fb_share_name, placeItem.getName()),
					getString(R.string.fb_share_caption),
					getString(R.string.fb_share_description),
					getString(R.string.fb_share_link),
					getString(R.string.fb_share_picture)
					);
		}else{
			Toast.makeText(this, R.string.err_no_internet, Toast.LENGTH_LONG).show();
		}
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {		
		facebookConnection.facebookAuthorizeCallback(requestCode, resultCode, data);
	}
	
	// Comments -----------------------------------------------
	private void loadComments(){
		if(Utils.isInternetAvailable(this)){
			final CommentLoadConnection clc = new CommentLoadConnection();
			clc.setPlaceID(placeItem.getId());
			clc.setNotify(new CommentLoadConnection.Notify() {
				public void onSuccess() {
					updateComments(clc.getComments());
				}			
				public void onError() {
					Toast.makeText(PlaceActivity.this, clc.getErrorText(), Toast.LENGTH_LONG).show();
				}
			});
			clc.start();
		}
	}
	
	private void updateComments(List<Comment> comments){
		if(commentAdapter == null){
			commentAdapter = new CommentAdapter(comments);
			placeListView.setAdapter(commentAdapter);
		}else{
			commentAdapter.changeList(comments);
		}
	}
	
	private void sendComment(){
		// 0.) Bejelentkezés ellenőrzése	
		if(!loginHandler.isLoggedIn()){
			loginHandler.showLoginDialog(getString(R.string.login_requirement_for_comments));
			return;
		}
		
		// 1.) Adatok levétele
		String commentText = newCommentEditText.getText().toString().trim();
				
		// 2.) Validáció
		if(commentText.length() < 10){
			this.dialog = new BUGDialog(this);		
			this.dialog.setTitle(R.string.errors);
			this.dialog.setMessage(R.string.err_invalid_comment_text);			
			this.dialog.setPositiveButton(R.string.ok, null);
			this.dialog.show();
			return;
		}
				
		// 3.) Adatok küldése		
		if(Utils.isInternetAvailable(this)){
			final CommentSendConnection csc = new CommentSendConnection();
			csc.setMemberID(loginHandler.getLoginuser());
			csc.setPlaceID(placeItem.getId());
			csc.setComment(commentText);
			csc.setDate(new Date());
			csc.setNotify(new CommentSendConnection.Notify(){
				public void onSuccess() {
					loadComments();
					newCommentEditText.setText(null);
					newCommentEditText.setEnabled(true);
					newCommentSendButton.setEnabled(true);
					Toast.makeText(PlaceActivity.this, R.string.comment_sent_successfully, Toast.LENGTH_LONG).show();
				}
				public void onError() {
					dialog = new BUGDialog(PlaceActivity.this);		
					dialog.setTitle(R.string.errors);
					dialog.setMessage(csc.getErrorText());			
					dialog.setPositiveButton(R.string.ok, null);
					dialog.show();
					
					newCommentEditText.setEnabled(true);
					newCommentSendButton.setEnabled(true);
				}
			});
			csc.start();
			newCommentEditText.setEnabled(false);
			newCommentSendButton.setEnabled(false);
		}else{
			Toast.makeText(this, R.string.err_no_internet, Toast.LENGTH_LONG).show();
		}
		
	}
	
	private void useTheDeal(){
		// 0.) Ellenőrzések:
		// 0.a) Be van-e jelentkezve
		if(!loginHandler.isLoggedIn()){
			loginHandler.showLoginDialog(getString(R.string.login_requirement_for_deals));
			return;
		}
		
		// 0.b) Pozíció meglétének ellenőrzése
		if(latestKnowLocation == null){
			this.dialog = new BUGDialog(this);		
			this.dialog.setTitle(R.string.errors);
			this.dialog.setMessage(getString(R.string.err_deal_location) + "\n" + getString(R.string.err_map_missing_from));			
			this.dialog.setPositiveButton(R.string.ok, null);
			this.dialog.setNegativeButton(R.string.settings, new OnClickListener() {
				public void onClick(View v) {
					startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
					dialog.dismiss();
				}
			});
			this.dialog.show();
			return;
		}
		
		// 0.c) Pozíció közelségének ellenőrzése
		if(latestKnowLocation.distanceTo(placeItem.getLocation()) > 100){
			this.dialog = new BUGDialog(this);		
			this.dialog.setTitle(R.string.errors);
			this.dialog.setMessage(getString(R.string.err_deal_location));			
			this.dialog.setPositiveButton(R.string.ok, null);
			this.dialog.show();
			return;
		}
		
		// 1.) Discount felhasználásának elkezdése
		DiscountHandler dh = new DiscountHandler(placeItem);
		// 1.a) Van-e elérhető kedvezmény
		if(dh.isInfinityDiscounts() || dh.hasDiscount()){
			// 1.b) Most érvényes-e a kedvezmény
			if(dh.isAvailableNow()){
				
				// 2.) Szerver kommunikáció
				if(Utils.isInternetAvailable(this)){
					final String voucherID = DiscountHandler.generateVoucherID(this);
					final DealConnection dc = new DealConnection();
					dc.setMemberID(loginHandler.getLoginuser());
					dc.setPlaceID(placeItem.getId());
					dc.setVoucherID(voucherID);
					dc.setNotify(new DealConnection.Notify() {
						public void onSuccess() {
							// 3.) Értesítés és a kedvezmény képernyő felmutatása	
							dbHandler.dealReduceRemaining(placeItem.getId());
							Toast.makeText(PlaceActivity.this, dc.getResultText(), Toast.LENGTH_LONG).show();
							UseDealSuccessActivity.openActivity(PlaceActivity.this, placeItem.getId(), voucherID);
							// TODO: Adatbázis frissítés?
						}					
						public void onError() {
							dialog = new BUGDialog(PlaceActivity.this);		
							dialog.setTitle(R.string.deals);
							dialog.setMessage(dc.getResultText() != null ? dc.getResultText() : dc.getErrorText());			
							dialog.setPositiveButton(R.string.ok, null);
							dialog.show();
						}
					});
					dc.start();
				}else{
					Toast.makeText(this, R.string.err_no_internet, Toast.LENGTH_LONG).show();
				}
				
			}else{
				dialog = new BUGDialog(PlaceActivity.this);		
				dialog.setTitle(R.string.deals);
				dialog.setMessage(getString(R.string.err_deal_duration, placeItem.getDiscountStart(), placeItem.getDiscountEnd()));			
				dialog.setPositiveButton(R.string.ok, null);
				dialog.show();
			}
		}else{
			dialog = new BUGDialog(PlaceActivity.this);		
			dialog.setTitle(R.string.deals);
			dialog.setMessage(R.string.err_deal_sold_out);			
			dialog.setPositiveButton(R.string.ok, null);
			dialog.show();
		}
		
	}
	
	@SuppressLint("NewApi")
	private void showContactsMapAndMore(){
		// 1.) Összeszedni a meglévő adatokat
		final List<ContactMenu> contacts = new ArrayList<ContactMenu>();	
		// 1.a) Nyitvatartás
		if(placeItem.getOpeningHour() != null && placeItem.getOpeningHour().length() > 2)
			contacts.add(new ContactMenu(ContactMenu.TYPE_TEXT, placeItem.getOpeningHour(), getString(R.string.contact_opening_hour)));
		// 1.b) Telefon
		if(placeItem.getTelephone() != null && placeItem.getTelephone().length() > 2)
			contacts.add(new ContactMenu(ContactMenu.TYPE_URI, "tel:" + placeItem.getTelephone(), getString(R.string.contact_telephone)));		
		// 1.c) WebURL
		if(placeItem.getWebsite() != null && placeItem.getWebsite().length() > 2)
			contacts.add(new ContactMenu(ContactMenu.TYPE_URI, placeItem.getWebsite(), getString(R.string.contact_website)));		
		// 1.d) Map
		contacts.add(new ContactMenu(ContactMenu.TYPE_MAP, "" + placeItem.getId(), getString(R.string.contact_map)));
				
		// 2. Dialogot formázni
		String[] items = new String[contacts.size()];
		for(int i=0; i<items.length; i++)
			items[i] = contacts.get(i).toString();
		
		AlertDialog.Builder builder = Build.VERSION.SDK_INT < 11 ? 
				new AlertDialog.Builder(this) : 
				new AlertDialog.Builder(this,android.R.style.Theme_Holo_Dialog_NoActionBar);
		builder.setItems(items, new DialogInterface.OnClickListener() {
		    public void onClick(DialogInterface dialog, int item) {
		        ContactMenu cm = contacts.get(item);
		        if(cm.getType() == ContactMenu.TYPE_URI){	
		        	Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(cm.getSource()));
		        	try{ startActivity(i); }catch (Exception e) {}
		        }else if(cm.getType() == ContactMenu.TYPE_TEXT){
		        	AlertDialog.Builder builder = new AlertDialog.Builder(PlaceActivity.this);
		        	builder.setMessage(cm.getSource());
		        	builder.setPositiveButton(R.string.ok, null);
		        	builder.show();
		        }else if(cm.getType() == ContactMenu.TYPE_MAP){
		        	MapsActivity.showOnMap(PlaceActivity.this, Integer.parseInt(cm.getSource()));
		        }
		    }
		});
		AlertDialog alert = builder.create();
		alert.show();
		
		// 3. Kezelni az eseményt
	}
	
	public static void showPlaceBy(Context context, String idBy, int id){
		Intent i = new Intent(context, PlaceActivity.class);
		i.putExtra(idBy, id);
		context.startActivity(i);
	}

}
